package com.crl.module.live
{
	import com.crl.utils.Delegate;
	import com.crl.utils.FMSUtil;
	
	import flash.events.NetStatusEvent;
	import flash.events.StatusEvent;
	import flash.media.Camera;
	import flash.media.Microphone;
	import flash.media.SoundTransform;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	
	/**
	 *  发布者封装,只用于视频音频流发布.
	 * @author crl
	 * 
	 */	
	public class Publisher extends AbstractLive
	{
		/**
		 * 视频流的默认配置; 
		 */		
		public static var defaultVideoHeight:int=240;
		public static var defaultVideoWidth:int=320;
		public static var defaultVideoBandWidth:int = 64000;
		public static var defaultVideoQuality:int = 85;
		public static var defaultVideoFrameRate:int = 12;
		
		
		
		private var camera:Camera;
		private var micphone:Microphone;		
		
		private var publisherVO:PublisherVO;
		public function Publisher(singleLive:SingleLive)
		{
			super(singleLive);
		}
		
		
		/**
		 * 设置视频的是否发布; 必须保证有成功的网络流;
		 * @param bool
		 * 
		 */		
		override public function set videoStatus(bool:Boolean):void{
			super.videoStatus=bool;
			
			if(stream==null)return;
			
			if (getCamara() != null && bool)
            {
                singleLive.showVideos(camera);
                stream.attachCamera(camera);
            }
            else
            {
            	this.singleLive.closeVideos();
            	stream.attachCamera(null);
            }
		}
		
		/**
		 * 设置	音频的是否发布; 必须保证有成功的网络流;
		 * @param bool
		 * 
		 */		
		public function set audioStatus(bool:Boolean):void{
			if(stream==null)return;
			if (getMicphone() != null && bool)
            {
                stream.attachAudio(micphone);
            }
            else
            {
            	stream.attachAudio(null);
            }
		}
		
		override public function set volume(value:Number) : void{
			super.volume=value;
			
			return;
			/*if(value==0){
				this.audioStatus=false;
			}else{
				this.audioStatus=true;
			}*/
			
			
			
			
			//todo delete;
			getMicphone();
			
			var soundTransform:SoundTransform=micphone.soundTransform;
			soundTransform.volume=value;
			
			micphone.soundTransform=soundTransform;
		}
		
		/**
		 * 发布视频; 它将会使连接对像的引用数加1,用于是否断开连接的凭据;
		 * @param name
		 * @param videoEnable
		 * 
		 */		
		public function publish(name:String,hashKey:String,videoEnable:Boolean=true):void{
			clearTimeout(timeoutResetToLiveInterval);
			
			if(singleLive.sharerConnection.isConnected==false){
        		singleLive.sharerConnection.doConnection(Delegate.create(publish,name,hashKey,videoEnable));
        		return;
        	}
			
			conn=singleLive.sharerConnection.getConnection();
			
        	stream = FMSUtil.createNetStream(conn,stream);
            if (stream == null)return;
            
            this.videoStatus=videoEnable;
            this.audioStatus=true;
            
            //发布者应该不用缓冲这个秒数吧;
            stream.bufferTime=0.01;
            stream.client=client;
            stream.publish(name);
            this.isRunning=true;
            singleLive.sharerConnection.getReferences().put(this,this);
            
            
            getPublisherVO().name=name;
        	publisherVO.hashKey=hashKey;
        	publisherVO.videoEnable=videoEnable;
        	conn.addEventListener(NetStatusEvent.NET_STATUS,status);
            
            //猥琐的代码开始;
            //var commandInfo:CommandInfo=new CommandInfo("cg",{name:name,key:hashKey,videoEnable:videoEnable,hasCamera:camera!=null,hasMic:micphone!=null,fk:CoreGlobals.currentUesrInfo.guid});
            //commandInfo.send();
		}
		
		
		/**
		 * 关闭发布网络流.并清空侦听; 
		 * 
		 */		
		override public function close():void{
			super.close();
			if(conn){
				conn.removeEventListener(NetStatusEvent.NET_STATUS,status);
				conn=null;
			}
			if(stream){
				stream=null;
			}
			lostLineCount=0;
			publisherVO=null;
			//camera=null;
			//micphone=null;
		}
		
		
		private function getPublisherVO():PublisherVO{
			if(publisherVO==null){
				publisherVO=new PublisherVO();
			}
			return publisherVO;
		}
		
		override protected function status(event:NetStatusEvent):void{
			var code:String=event.info.code;
	 		switch(code){
				case LiveConst.CLOSED:
					//在status状态，是不可以进行直接的连接,必抛错误,所以用calllater;
					republishCallLater(publisherVO);
					break;
	 		}
	 	}
	 	
	 	
	 	/**
	 	 * 延迟重连; (发布者用1000,接收者用3000,这样只要发布者成功.接收者就不必做重连操作);
	 	 * @param vo
	 	 * 
	 	 */	 	
	 	private function republishCallLater(vo:PublisherVO):void{
	 		if(vo==null)return;
	 		
	 		var name:String=vo.name.split("_")[0];
			name+="_"+lostLineCount++;
			
			clearTimeout(timeoutResetToLiveInterval);
	 		timeoutResetToLiveInterval=setTimeout(this.preRePublish,LiveConst.PUBLISHER_RECONN_TICK,name,vo.hashKey,vo.videoEnable);
	 	}
	 	
	 	
	 	/**
	 	 * 在重新发布之前; 
	 	 * @param name
	 	 * @param hashKey
	 	 * @param videoEnable
	 	 * 
	 	 */	 	
	 	private function preRePublish(name:String,hashKey:String,videoEnable:Boolean):void{
	 		//HelpTipsPanel.show(RFMessage.generateMessage(SJMessageCode.ROOM_VIDEO_INFO_001),HelpTipsPanel.ICON_SOCIAL);
	 		this.publish(name,hashKey,videoEnable);
	 	}
		
		
		/**
		 * 取得摄像头; 
		 * @return 
		 * 
		 */		
		private function getCamara():Camera{
			if(camera==null){
				camera =FMSUtil.getCamera();
				
			}
			if(camera){
				/**
            	 * 重新设置视频质量;
            	 * */
                camera.setMode(defaultVideoWidth, defaultVideoHeight, defaultVideoFrameRate);
                camera.setQuality(defaultVideoBandWidth, defaultVideoQuality);
                camera.addEventListener(StatusEvent.STATUS, cameraStatusHandler) ;
                camera.setLoopback(true);
			}
			return camera;
		}
		
		/**
		 * 视频状态变化时; 
		 * @param event
		 * 
		 */		
		private function cameraStatusHandler(event:StatusEvent):void{
			switch(event.code){
				case "Camera.Muted" :
					trace("Camera Access Has Been Denied!");
					break;
				case "Camera.Unmuted" :
					trace("Camera Access Has Been Granted");
					break;
		    }

		}
		
		/**
		 * 取得麦克风; 
		 * @return 
		 * 
		 */		
		private function getMicphone():Microphone{
			if(micphone==null){
				micphone = FMSUtil.getMicrophone();
			}
			if(micphone){
				/**
            	 * 重新设置麦克风质量;
            	 * */
                micphone.rate = 22;
                micphone.setLoopBack(false);
                micphone.setSilenceLevel(0);
                micphone.setUseEchoSuppression(true);
			}
			return micphone;
		}		

	}
}


/**
 *  
 * @author crl
 * 
 */
class PublisherVO{
	public var name:String;
	public var hashKey:String;
	public var videoEnable:Boolean;
	public function PublisherVO(){
		
	}
}